package controllers;

import com.google.gson.JsonObject;

import play.libs.Mail;
import play.mvc.Controller;
import play.mvc.With;
import play.test.Fixtures;

import java.util.*;

import com.google.gson.JsonObject;

import models.*;

@With(Secure.class)
public class TopicIdeaController extends Controller {
	/**
	 * renders the page createTopic
	 */
	public static void createTopic() {
		IdeaDeveloper ideaDeveloper = new IdeaDeveloper();
		ideaDeveloper.save();
		Entities entity = new Entities();
		entity.save();
		long id = entity.id;
		String type = "entity";
		render(ideaDeveloper, id, type);
	}

	/**
	 * hides the button issue
	 * 
	 * @author Dina
	 * @param topicId
	 *            the id of the topic
	 * 
	 */
	public static void hideButtonIssue(long topicId) {
		Topic topic = Topic.findById(topicId);
		// IdeaDeveloper id = (IdeaDeveloper)IdeaDeveloper.find("id=?",
		// idevid).fetch().get(0);
		// boolean x = checkOrganizerAuthority(id, topic);
		// boolean y = checkVotedBefore();
		JsonObject json = new JsonObject();
		json.addProperty("showHideButton", !topic.hidden);
		renderJSON(json.toString());
	}

	/**
	 * checks if button should be hidden or not
	 * 
	 * @param ideaDeveloperId
	 * @param topicId
	 */
	public static void hideButton(long ideaDeveloperId, long topicId) {
		Topic topic = Topic.findById(topicId);
		IdeaDeveloper id = IdeaDeveloper.findById(ideaDeveloperId);
		boolean x = checkOrganizerAuthority(id, topic);
		// boolean y = checkVotedBefore();
		JsonObject json = new JsonObject();
		json.addProperty("showHideButton", x);
		renderJSON(json.toString());
	}

	/**
	 * checks if the the organizer have authority on the topic or not
	 * 
	 * @param id
	 *            the id of the developer "organizer"
	 * @param topic
	 *            the topic to check its authority
	 * @return true if the idea developer have authority, false if not
	 *         Authorized
	 */
	public static boolean checkOrganizerAuthority(IdeaDeveloper id, Topic topic) {
		ArrayList<IdeaDeveloper> authorized = new ArrayList<IdeaDeveloper>();
		authorized.add(topic.creator);
		boolean flag = false;
		if (topic.topicEnt != null) {

			Entities e = topic.topicEnt;
			while (e.parent != null) {
				for (int i = 0; i < e.managers.size(); i++) {
					authorized.add(e.managers.get(i).ideaDeveloper);
				}
				e = e.parent;
			}
			for (int i = 0; i < e.liesIn.managers.size(); i++) {
				authorized.add(e.liesIn.managers.get(i).ideaDeveloper);
			}

		}
		if (topic.topicOrg != null) {
			for (int i = 0; i < topic.topicOrg.managers.size(); i++) {
				authorized.add(topic.topicOrg.managers.get(i).ideaDeveloper);
			}
		}

		return authorized.contains(id);
	}

	// public static boolean checkVotedBefore(IdeaDeveloper id, Topic topic) {
	//
	// }

	/**
	 * hides the topic
	 * @author Dina
	 * 
	 * @param topicId
	 *            the topic to be hidden
	 */
	public static void hideTopic(long topicId) {
		Topic t = Topic.findById(topicId);
		JsonObject json = new JsonObject();
		t.hideTopic();
		// t.title = "This is now a hidden topic";
		t.save();
//		for (int i = 0; i < t.joined.size(); i++) {
//			IdeaDeveloper ideaDeveloper = t.joined.get(i);
//
//			ideaDeveloper.joinedTop.remove(t);
//			ideaDeveloper.save();
//			json.addProperty("loop after " + i,
//					ideaDeveloper.joinedTop.contains(t));
//		}
//		while (!t.joined.isEmpty()) {
//			t.joined.remove(0);
//			t.save();
//		}
//		t.save();
//		for (int i = 0; i < t.followed.size(); i++) {
//			IdeaDeveloper ideaDeveloper = t.followed.get(i);
//			json.addProperty("loop before " + i,
//					ideaDeveloper.followedTop.contains(t));
//			ideaDeveloper.followedTop.remove(t);
//			ideaDeveloper.save();
//			json.addProperty("loop after " + i,
//					ideaDeveloper.followedTop.contains(t));
//		}
//		while (!t.followed.isEmpty()) {
//			t.followed.remove(0);
//			t.save();
//		}
		// ideaDeveloper.followedTop = new ArrayList<IdeaDeveloper>();
		// t.followed.clear();

//		for (int i = 0; i < t.managers.size(); i++) {
//			t.joined.add(t.managers.get(i).ideaDeveloper);
//			t.save();
//			t.managers.get(i).ideaDeveloper.joinedTop.add(t);
//			t.managers.get(i).ideaDeveloper.save();
			// t.managers.get(i).ideaDeveloper.joinedTop.add(t);
			// t.managers.get(i).ideaDeveloper.save();
//		}
//		t.joined.add(t.creator);
//		t.save();
//		t.creator.joinedTop.add(t);
//		t.creator.save();
		boolean flag = ((Topic) Topic.find("id=?", t.id).fetch().get(0)).hidden;

		if (flag) {
			json.addProperty("x", "hidden Successfully");
		} else {
			json.addProperty("x", "la2 msh hidden");
		}
		renderJSON(json.toString());

	}

	/**
	 * unhides topic
	 * 
	 * @param topicId
	 *            the topic to be un hidden
	 */
	public static void unhideTopic(long topicId) {
		Topic t = (Topic) Topic.find("id=?", topicId).fetch().get(0);
		t.hidden = false;
		t.save();
		boolean flag = false;
		JsonObject json = new JsonObject();
		if (flag) {
			json.addProperty("x", "hidden Successfully");
		} else {
			json.addProperty("x", "la2 msh hidden");
		}
		renderJSON(json.toString());
	}

	/**
	 * invite user to topic
	 * 
	 * @param topicId
	 *            the id of the topic to invite to
	 */
	public static void inviteToTopic(long topicId) {
		Topic t = Topic.findById(topicId);
		List<IdeaDeveloper> devs = new ArrayList<IdeaDeveloper>();
		devs = t.invitees();
		JsonObject json = new JsonObject();
		json.addProperty("size", devs.size());
		String names = null;
		if (!devs.isEmpty()) {

			names = "";

			int i = 0;
			for (i = 0; i < devs.size() - 1; i++) {

				if (!t.joined.contains(devs.get(i))) {
					names = names + devs.get(i).username + "^";
				}
			}
            if(devs.size()>0){
			if (!t.joined.contains(devs.get(i)))
				names = names + devs.get(i).username;
            }
		}
		json.addProperty("names", names);
		renderJSON(json.toString());

	}

	/**
	 * allows user to vote for idea
	 * 
	 * @param ideaId
	 *            the idea user is voting for
	 * 
	 */
	public static void voteForIdea(long ideaId) {
		long ideaDeveloperId = Security.userid();
		IdeaDeveloper ideaDev = (IdeaDeveloper) IdeaDeveloper
				.findById(ideaDeveloperId);

		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		// JsonObject json = new JsonObject();
		if (idea.vote.contains(ideaDev)) {
			// json.addProperty("x", "You can't vote twice!");
		} else {
			idea.vote(ideaDeveloperId);
			// idea.vote.add(ideaDev);
			ideaDev.incrementCounter(1);
			// ideaDev.voteIdea.add(idea);
			// json.addProperty("x", idea.noOfVotes);
		}
		// renderJSON(json.toString());

	}

	/**
	 * allows user to cancel his vote for idea
	 * 
	 * @param ideaId
	 *            the idea user canceling his vote for
	 */
	public static void unvoteForIdea(long ideaId) {
		long ideaDeveloperId = Security.userid();
		IdeaDeveloper ideaDev = IdeaDeveloper.findById(ideaDeveloperId);
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		JsonObject json = new JsonObject();
		if (idea.vote.contains(ideaDev)) {
			idea.unvote(ideaDeveloperId);
			// idea.vote.remove(ideaDev);
			ideaDev.decrementCounter(1);
			// idea.save();
			// ideaDev.voteIdea.remove(idea);
			// ideaDev.save();
		} else {
			json.addProperty("x", "You can't unvote before vote!");
		}
	}

	/**
	 * gets the number of votes for idea
	 * 
	 * @param ideaId
	 *            the idea getting the number of votes for
	 */
	public static void noOfVotes(long ideaId) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		JsonObject json = new JsonObject();
		json.addProperty("votes", idea.noOfVotes);
		renderJSON(json.toString());
	}

	/**
	 * invite the idea developer to topic
	 * 
	 * @param topicId
	 *            the topic to invite user to
	 * @param ideaDeveloperId
	 *            the user invited to the topic
	 */
	public static void inviteIdeaDev(long topicId, String ideaDeveloperName) {
		Topic t = Topic.findById(topicId);
		IdeaDeveloper idev = (IdeaDeveloper) IdeaDeveloper
				.find("username=?", ideaDeveloperName).fetch().get(0);
		long ideaDeveloperId = idev.id;
		t.inviteToHidden(ideaDeveloperId);
		// t.joined.add(idev);
		// t.save();

	}
/**
 * it creates a topic in entity but it is drafted no one can see it expect the creator
 * @author : amira
 * @param title
 *  title of the topic
 * @param description
 *  description of the topic
 * @param visibility
 *  visibility of the topic wether it is hidden or public
 * @param entityId
 * entity where the topic exist
 */
	public static void draftTopicEntity(String title, String description,

	String visibility, long entityId) {
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		Topic topic = Topic.createTopicEnt(title, description, entityId,
				ideaDeveloper.id);
		JsonObject draftTopicInfo = new JsonObject();
		if (topic != null) {
			if (visibility.equals("Hidden")) {
				topic.hideTopic();
			}
			draftTopicInfo.addProperty("topicId", topic.id);
			draftTopicInfo.addProperty("topicTitle", topic.title);
                       draftTopicInfo.addProperty("topicDescription",
					topic.description);

		}

		renderJSON(draftTopicInfo.toString());

	}

	/**
	 * allows user to create a topic in entity and post it
	 * @author :amira
	 * @author Amira
	 * 
	 * @param title
	 *            title of the topic
	 * @param description
	 *            the description of the topic
	 * @param visibility
	 *            the visibility "privacy" of the topic
	 * @param entityId
	 *            the entity's id where the topic is created
	 * @param IdeaDeveloperId
	 *            the idea developer's id creating topic
	 */
	public static void postTopicEntity(String title, String description,

	String visibility, long entityId) {
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		Topic topic = Topic.createTopicEnt(title, description, entityId,
				ideaDeveloper.id);
		JsonObject createdTopicInfo = new JsonObject();
		if (topic != null) {
			if (visibility.equals("Hidden")) {
				topic.hideTopic();
			}

			topic.postATopic();
			createdTopicInfo.addProperty("topicId", topic.id);
			createdTopicInfo.addProperty("topicTitle", topic.title);

		}

		renderJSON(createdTopicInfo.toString());

	}

	/**

	 * allows user to create and post topic in organization
	 
	 * @author Amira
	 * 
	 * @param title
	 *            title of the topic
	 * @param description
	 *            the description of the topic
	 * @param visibility
	 *            the visibility "privacy" of the topic
	 * @param orgId
	 *            the organization's id where the topic is created
	 * @param IdeaDeveloperId
	 *            the idea developer's id creating topic
	 */
	public static void postTopicOrganization(String title, String description,

	String visibility, long orgId) {
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		Topic topic = Topic.createTopicOrg(title, description, orgId,
				ideaDeveloper.id);
		JsonObject createdTopicInfo = new JsonObject();
		if (topic != null) {
			if (visibility.equals("Hidden")) {
				topic.hideTopic();
			}

			topic.postATopic();

			createdTopicInfo.addProperty("topicId", topic.id);
			createdTopicInfo.addProperty("topicTitle", topic.title);
		}

		renderJSON(createdTopicInfo.toString());
	}

        /**
	 * allows user to create and draft topic in organization , no one can see it except the creator
	 * @author : amira
	 * @param title
	 *            title of the topic
	 * @param description
	 *            the description of the topic
	 * @param visibility
	 *            the visibility "privacy" of the topic
	 * @param orgId
	 *            the organization where the topic is created
	 * @param IdeaDeveloperId
	 *            the idea developer creating topic
	 */
	public static void draftTopicOrganization(String title, String description,

	String visibility, long orgId) {
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		Topic topic = Topic.createTopicOrg(title, description, orgId,
				ideaDeveloper.id);

		JsonObject draftTopicInfo = new JsonObject();
		if (topic != null) {
			if (visibility.equals("Hidden")) {
				topic.hideTopic();
			}
			draftTopicInfo.addProperty("topicId", topic.id);
			draftTopicInfo.addProperty("topicTitle", topic.title);
                          draftTopicInfo.addProperty("topicDescription",
					topic.description);
		}

		renderJSON(draftTopicInfo.toString());

	}

        /**
         * post a topic after being drafted
         * @author :amira
         * @param topicId
         *     the id of the topic which will be posted
         * @param title
         *   given title in case that the title is changed
         * @param description
         *   given description in case the description is changed
         * @param visibility
         *     Visibility of the topic in case it is changed
         */

	public static void postDraftTopic(long topicId, String title,
			String description, String visibility) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);

		topic.title = title;
		topic.description = description;
                topic.save();
		if (visibility.equals("Hidden")) {
			topic.hideTopic();
		}

		topic.postATopic();
                 JsonObject json = new JsonObject();
		json.addProperty("topicTitle", topic.title);
		json.addProperty("topicId", topic.id);
                json.addProperty("topicDescription", topic.description);
		renderJSON(json.toString());
	}
        /**
         * edit a drafted topic and draft it again
         * @author :amira
         * @param topicId
         *         the id of the topic
         * @param title
         *        the modified title
         * @param description
         *         the modified  description
         * @param visibility
         *          the modified visibility
          */
        public static void draftDraftTopic(long topicId,String title,String description,String visibility ) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);
                topic.title=title;
                topic.description=description;
                topic.save();
                if (visibility.equals("Hidden")) {
				topic.hideTopic();
			}
                JsonObject json = new JsonObject();
		json.addProperty("topicTitle", topic.title);
		json.addProperty("topicId", topic.id);
                json.addProperty("topicDescription", topic.description);
		renderJSON(json.toString());
		
	}
        /**
         * get ideas of a topic with all privileges
         * @author: amira
         * @param topicId
         *     the id of the topic
         * @param ideaDeveloperId
         *     the id of the ideaDeveloper viewing the topic to get the privileges
         * @param page
         *       int to fetch what 5 ideas from the database
         * @param total
         *        total number of ideas
         */

	public static void displayIdeasTopics(long topicId, long ideaDeveloperId,
			String page, String total) {
		int pp = Integer.parseInt(page);
		int totaltotal = Integer.parseInt(total);
		int count = 0;
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);
		String username = ((IdeaDeveloper) IdeaDeveloper
				.find("id=?", ideaDeveloperId).fetch().get(0)).username;

		int size = Idea.find("published=? and ideaTopic=? ", true, topic)
				.fetch().size();
		List<Idea> postIdeas;

		if (size != 0) {
			postIdeas = Idea
					.find("published=? and ideaTopic=? order by dateOfDraftingPosting DESC",
							true, topic).fetch(pp, 5);
		} else {
			postIdeas = Idea.find("published=? and ideaTopic=? ", true, topic)
					.fetch();
		}

		totaltotal = totaltotal + postIdeas.size();
		if (size - totaltotal != 0) {
			count = 1;
			pp = pp + 1;
		}

		List<Idea> draftedIdeas = Idea.find(
				"published=? and ideaTopic=? and creator.id=?", false, topic,
				ideaDeveloperId).fetch();
		List<Idea> voted = Idea
				.find("select d from Idea d join d.vote as dd where d.ideaTopic=? and dd.username like ?",
						topic, username).fetch();
		List<Idea> report = Idea
				.find("select d from Idea d join d.spam as dd where d.ideaTopic=? and dd.username like ?",
						topic, username).fetch();
		String numberOfReported = "";
		String ideasDescription = "";
		String ideasTitle = "";
		String ideasId = "";
		String ideaDeveloperName = "";
		String ideaDeveloperIds = "";
		String IdeasVotedId = "";
		String ideasdrafted = "";
		String ideasdraftedTitle = "";
		String ideasdraftedId = "";
		String promoted = "";
		int topicPromoted = 0;
		int topicHidden = 0;
		String ideasReported = "";
		String numberOfVotes = "";
		String actionPlans = "";

		// String ideasTilte="";
		for (int i = 0; i < postIdeas.size(); i++) {
			if (i < postIdeas.size() - 1) {
				ideasDescription = ideasDescription
						+ postIdeas.get(i).description + "&&";
				ideasTitle = ideasTitle + postIdeas.get(i).title + "&&";
				ideasId = ideasId + postIdeas.get(i).id + "&&";
				ideaDeveloperName = ideaDeveloperName
						+ postIdeas.get(i).creator.username + "&&";
				ideaDeveloperIds = ideaDeveloperIds
						+ postIdeas.get(i).creator.id + "&&";
				if (voted.contains(postIdeas.get(i))) {
					IdeasVotedId = IdeasVotedId + 1 + "&&";
				} else {
					IdeasVotedId = IdeasVotedId + 0 + "&&";
				}
				if (postIdeas.get(i).promotedForExecution == true) {
					promoted = promoted + 1 + "&&";
					topicPromoted = 1;
				} else {
					promoted = promoted + 0 + "&&";
				}

				if (report.contains(postIdeas.get(i))) {
					ideasReported = ideasReported + 1 + "&&";
				} else {
					ideasReported = ideasReported + 0 + "&&";
				}
				if (postIdeas.get(i).ideaPlan != null) {
					actionPlans = actionPlans + postIdeas.get(i).ideaPlan.id
							+ "&&";
				} else {
					actionPlans = actionPlans + 0 + "&&";
				}
				numberOfVotes = numberOfVotes + postIdeas.get(i).noOfVotes
						+ "&&";
				numberOfReported = numberOfReported
						+ postIdeas.get(i).spam.size() + "&&";
			} else {
				ideasDescription = ideasDescription
						+ postIdeas.get(i).description;
				ideasTitle = ideasTitle + postIdeas.get(i).title;
				ideasId = ideasId + postIdeas.get(i).id;
				ideaDeveloperName = ideaDeveloperName
						+ postIdeas.get(i).creator.username;
				ideaDeveloperIds = ideaDeveloperIds
						+ postIdeas.get(i).creator.id;
				if (voted.contains(postIdeas.get(i))) {
					IdeasVotedId = IdeasVotedId + 1;
				} else {
					IdeasVotedId = IdeasVotedId + 0;
				}
				if (postIdeas.get(i).promotedForExecution == true) {
					promoted = promoted + 1;
					topicPromoted = 1;
				} else {
					promoted = promoted + 0;
				}

				if (report.contains(postIdeas.get(i))) {
					ideasReported = ideasReported + 1;
				} else {
					ideasReported = ideasReported + 0;
				}

				if (postIdeas.get(i).ideaPlan != null) {
					actionPlans = actionPlans + postIdeas.get(i).ideaPlan.id;
				} else {
					actionPlans = actionPlans + 0;
				}
				numberOfVotes = numberOfVotes + postIdeas.get(i).noOfVotes;
				numberOfReported = numberOfReported
						+ postIdeas.get(i).spam.size();
			}

		}

		if (draftedIdeas.size() != 0) {
			for (int i = 0; i < draftedIdeas.size() - 1; i++) {
				ideasdrafted = ideasdrafted + draftedIdeas.get(i).description
						+ "&&";
				ideasdraftedId = ideasdraftedId + draftedIdeas.get(i).id + "&&";
				ideasdraftedTitle = ideasdraftedTitle
						+ draftedIdeas.get(i).title + "&&";
			}

			ideasdrafted = ideasdrafted
					+ draftedIdeas.get(draftedIdeas.size() - 1).description;
			ideasdraftedId = ideasdraftedId
					+ draftedIdeas.get(draftedIdeas.size() - 1).id;
			ideasdraftedTitle = ideasdraftedTitle
					+ draftedIdeas.get(draftedIdeas.size() - 1).title;

		} // String x=ideaDeveloperId;
			// render(x);
			// Idea ideas =topic.ideas.get(topic.ideas.size()-1);

		if (topic.hidden == true) {
			topicHidden = 1;
		}

		JsonObject json = new JsonObject();
		json.addProperty("ideasDescription", ideasDescription);
		json.addProperty("ideasTitle", ideasTitle);
		json.addProperty("ideasId", ideasId);
		json.addProperty("ideaDeveloperName", ideaDeveloperName);
		json.addProperty("ideaDeveloperIds", ideaDeveloperIds);
		json.addProperty("IdeasVotedId", IdeasVotedId);
		json.addProperty("ideasdrafted", ideasdrafted);
		json.addProperty("ideasdraftedId", ideasdraftedId);
		json.addProperty("ideasdraftedTitle", ideasdraftedTitle);
		json.addProperty("promoted", promoted);
		json.addProperty("topicPromoted", topicPromoted);
		json.addProperty("topicHidden", topicHidden);
		json.addProperty("ideasReported", ideasReported);
		json.addProperty("numberOfVotes", numberOfVotes);
		json.addProperty("numberOfReported", numberOfReported);
		json.addProperty("page", pp);
		json.addProperty("count", count);
		json.addProperty("total", totaltotal);
		json.addProperty("actionPlans", actionPlans);

		renderJSON(json.toString());
	}

	/**
	 * 
	 * A method that returns a result indicating whether a certain user has
	 * already rated this topic.
	 * 
	 * @author Shahir
	 * 
	 * @param topicId
	 *            The long(Integer) ID of the topic that is being rated.
	 * 
	 */
	public static void alreadyRatedTopic(long topicId) {

		Topic topic = Topic.findById(topicId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		long count = Rate.count("ideaDeveloper = ? and topic = ?",
				ideaDeveloper, topic);

		JsonObject json = new JsonObject();

		if (count == 0) {
			json.addProperty("result", 0);
		} else {
			Rate rate = Rate.find("ideaDeveloper = ? and topic = ?",
					ideaDeveloper, topic).first();

			json.addProperty("result", rate.rating);
		}

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that returns a result indicating whether a certain user has
	 * already rated this idea
	 * 
	 * @author Shahir
	 * 
	 * @param ideaId
	 *            the long(Integer) ID of the idea that is being rated.
	 * 
	 */
	public static void alreadyRatedIdea(long ideaId) {

		Idea idea = Idea.findById(ideaId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		long count = Rate.count("ideaDeveloper = ? and idea = ?",
				ideaDeveloper, idea);

		JsonObject json = new JsonObject();

		if (count == 0) {
			json.addProperty("result", 0);
		} else {
			Rate rate = Rate.find("ideaDeveloper = ? and idea = ?",
					ideaDeveloper, idea).first();

			json.addProperty("result", rate.rating);
		}

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that returns a result indicating whether a certain user has
	 * already rated this action plan
	 * 
	 * @author Shahir
	 * 
	 * @param actionPlanId
	 *            the long(Integer) ID of the action plan that is being rated.
	 * 
	 */
	public static void alreadyRatedActionPlan(long actionPlanId) {

		ActionPlan actionPlan = ActionPlan.findById(actionPlanId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		long count = Rate.count("ideaDeveloper = ? and actionPlan = ?",
				ideaDeveloper, actionPlan);

		JsonObject json = new JsonObject();

		if (count == 0) {
			json.addProperty("result", 0);
		} else {
			Rate rate = Rate.find("ideaDeveloper = ? and actionPlan = ?",
					ideaDeveloper, actionPlan).first();

			json.addProperty("result", rate.rating);
		}

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that returns a result indicating whether a certain user has
	 * already rated this organization
	 * 
	 * @author Shahir
	 * 
	 * @param organizationId
	 *            the long(Integer) ID of the organization that is being rated.
	 * 
	 */
	public static void alreadyRatedOrganization(long organizationId) {

		Organization organization = Organization.findById(organizationId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		long count = Rate.count("ideaDeveloper = ? and organization = ?",
				ideaDeveloper, organization);

		JsonObject json = new JsonObject();

		if (count == 0) {
			json.addProperty("result", 0);
		} else {
			Rate rate = Rate.find("ideaDeveloper = ? and organization = ?",
					ideaDeveloper, organization).first();

			json.addProperty("result", rate.rating);
		}

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that returns a result indicating whether a certain user has
	 * already rated this entity.
	 * 
	 * @author Shahir
	 * 
	 * @param entityId
	 *            the long(Integer) ID of the entity that is being rated.
	 * 
	 */
	public static void alreadyRatedEntity(long entityId) {

		Entities entity = Entities.findById(entityId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		long count = Rate.count("ideaDeveloper = ? and entity = ?",
				ideaDeveloper, entity);

		JsonObject json = new JsonObject();

		if (count == 0) {
			json.addProperty("result", 0);
		} else {
			Rate rate = Rate.find("ideaDeveloper = ? and entity = ?",
					ideaDeveloper, entity).first();

			json.addProperty("result", rate.rating);
		}

		renderJSON(json.toString());

	}

	/**
	 * This method allows an organizer to change the priority of an idea.
	 * 
	 * @author Shahir
	 * 
	 * @param priority
	 *            The String representing the priority.
	 * @param ideaId
	 *            The long(Integer) ID of the idea that is being prioritized.
	 */
	public static void prioritizeIdea(String priority, long ideaId) {

		Idea idea = Idea.findById(ideaId);

		JsonObject json = new JsonObject();

		idea.priority = priority;

		idea.save();

		json.addProperty("result", priority);

		renderJSON(json.toString());

	}

	/**
	 * This method returns the priority of the given idea.
	 * 
	 * @author Shahir
	 * 
	 * @param ideaId
	 *            The long(Integer) ID of the idea for which the priority is required.
	 */
	public static void getIdeaPriority(long ideaId) {

		String priority;

		Idea idea = Idea.findById(ideaId);

		JsonObject json = new JsonObject();

		priority = idea.priority;

		json.addProperty("result", priority);

		renderJSON(json.toString());

	}

	/**
	 * This method returns the total rating for a given topic.
	 * 
	 * @author Shahir
	 * 
	 * @param topicId
	 *            The long(Integer) ID of the topic.
	 */

	public static void getTopicRating(long topicId) {

		int sum = 0;
		int validRates = 0;

		Topic topic = Topic.findById(topicId);

		for (int i = 0; i < topic.rates.size(); i++) {

			if (topic.rates.get(i).rating == 0)
				continue;

			sum += topic.rates.get(i).rating;

			validRates++;
		}

		JsonObject json = new JsonObject();

		if (validRates != 0)
			json.addProperty("result", (sum / validRates));
		else
			json.addProperty("result", 0);

		renderJSON(json.toString());
	}

	/**
	 * This method returns the total rating for a given idea.
	 * 
	 * @author Shahir
	 * 
	 * @param ideaId
	 *            The long(Integer) ID of the idea.
	 */

	public static void getIdeaRating(long ideaId) {

		int sum = 0;
		int validRates = 0;

		Idea idea = Idea.findById(ideaId);

		for (int i = 0; i < idea.rates.size(); i++) {

			if (idea.rates.get(i).rating == 0)
				continue;

			sum += idea.rates.get(i).rating;

			validRates++;
		}

		JsonObject json = new JsonObject();

		if (validRates != 0)
			json.addProperty("result", (sum / validRates));
		else
			json.addProperty("result", 0);

		renderJSON(json.toString());
	}

	/**
	 * This method returns the total rating for a given action plan.
	 * 
	 * @author Shahir
	 * 
	 * @param actionPlanId
	 *            The long(Integer) ID of the action plan.
	 */

	public static void getActionPlanRating(long actionPlanId) {

		int sum = 0;
		int validRates = 0;

		ActionPlan actionPlan = ActionPlan.findById(actionPlanId);

		for (int i = 0; i < actionPlan.rates.size(); i++) {

			if (actionPlan.rates.get(i).rating == 0)
				continue;

			sum += actionPlan.rates.get(i).rating;

			validRates++;
		}

		JsonObject json = new JsonObject();

		if (validRates != 0)
			json.addProperty("result", (sum / validRates));
		else
			json.addProperty("result", 0);

		renderJSON(json.toString());
	}

	/**
	 * This method returns the total rating for a given organization.
	 * 
	 * @author Shahir
	 * 
	 * @param organizationId
	 *            The long(Integer) ID of the organization.
	 */

	public static void getOrganizationRating(long organizationId) {

		int sum = 0;
		int validRates = 0;

		Organization organization = Organization.findById(organizationId);

		for (int i = 0; i < organization.rates.size(); i++) {

			if (organization.rates.get(i).rating == 0)
				continue;

			sum += organization.rates.get(i).rating;

			validRates++;
		}

		JsonObject json = new JsonObject();

		if (validRates != 0)
			json.addProperty("result", (sum / validRates));
		else
			json.addProperty("result", 0);

		renderJSON(json.toString());
	}

	/**
	 * This method returns the total rating for a given entity.
	 * 
	 * @author Shahir
	 * 
	 * @param entityId
	 *            The long(Integer) ID of the entity.
	 */

	public static void getEntityRating(long entityId) {

		int sum = 0;
		int validRates = 0;

		Entities entity = Entities.findById(entityId);

		for (int i = 0; i < entity.rates.size(); i++) {

			if (entity.rates.get(i).rating == 0)
				continue;

			sum += entity.rates.get(i).rating;

			validRates++;
		}

		JsonObject json = new JsonObject();

		if (validRates != 0)
			json.addProperty("result", (sum / validRates));
		else
			json.addProperty("result", 0);

		renderJSON(json.toString());
	}

	/**
	 * This method sends a request from the user to the specified organization.
	 * 
	 * @author Shahir
	 * 
	 * @param organizationName
	 *            The String representing the name of the organization that the user wished to join.
	 */

	public static void requestToJoinOrganization(String organizationName) {

		Organization organization = Organization.find("name = ?",
				organizationName).first();

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		JsonObject json = new JsonObject();

		for (int i = 0; i < ideaDeveloper.requests.size(); i++) {
			if (ideaDeveloper.requests.get(i).type.equals("JoinOrgFromDevToOrg")) {
				if (ideaDeveloper.requests.get(i).org.equals(organization)) {
					json.addProperty("result",
							"You have already requested to join this organization.");
					renderJSON(json.toString());
					return;
				}
			}
		}

		for (int i = 0; i < ideaDeveloper.joinedOrg.size(); i++) {

			if (ideaDeveloper.joinedOrg.get(i).equals(organization)) {
				json.addProperty("result",
						"You have already joined this organization.");
				renderJSON(json.toString());
				return;
			}

		}

		Request.RequestMe(organization, ideaDeveloper, "JoinOrgFromDevToOrg");

		json.addProperty("result", "Request sent.");

		renderJSON(json.toString());
	}

	/**
	 * This method sends a request from the user to the specified entity.
	 * 
	 * @author Shahir
	 * 
	 * @param entityName
	 *            The String representing the name of the entity that the user wished to join.
	 */

	public static void requestToJoinEntity(String entityName) {

		Entities entity = Entities.find("name = ?", entityName).first();

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		JsonObject json = new JsonObject();

		for (int i = 0; i < ideaDeveloper.requests.size(); i++) {
			if (ideaDeveloper.requests.get(i).type.equals("JoinEntFromDevToEnt")) {
				if (ideaDeveloper.requests.get(i).ent.equals(entity)) {
					json.addProperty("result",
							"You have already requested to join this entity.");
					renderJSON(json.toString());
					return;
				}
			}
		}

		for (int i = 0; i < ideaDeveloper.joinedEnt.size(); i++) {

			if (ideaDeveloper.joinedEnt.get(i).equals(entity)) {
				json.addProperty("result",
						"You have already joined this entity.");
				renderJSON(json.toString());
				return;
			}

		}

		Request.RequestMe(entity, ideaDeveloper, "JoinEntFromDevToEnt");

		json.addProperty("result", "Request sent.");

		renderJSON(json.toString());
	}

	/**
	 * This method sends a request from the user to the specified organization
	 * but is specific to advanced search.
	 * 
	 * @author Shahir
	 * 
	 * @param organizationName
	 *            The String representing the name of the organization that the user wished to join.
	 */

	public static void requestToJoinOrganizationAdv(String organizationName) {

		Organization organization = Organization.find("name = ?",
				organizationName).first();

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		JsonObject json = new JsonObject();

		for (int i = 0; i < ideaDeveloper.requests.size(); i++) {
			if (ideaDeveloper.requests.get(i).type.equals("JoinOrgFomDevToOrg")) {
				if (ideaDeveloper.requests.get(i).org.equals(organization)) {
					json.addProperty("result",
							"You have already requested to join this organization.");
					renderJSON(json.toString());
					return;
				}
			}
		}

		for (int i = 0; i < ideaDeveloper.joinedOrg.size(); i++) {

			if (ideaDeveloper.joinedOrg.get(i).equals(organization)) {
				json.addProperty("result",
						"You have already joined this organization.");
				renderJSON(json.toString());
				return;
			}

		}

		Request.RequestMe(organization, ideaDeveloper, "JoinOrgFromDevToOrg");

		json.addProperty("result", "Request sent.");

		renderJSON(json.toString());
	}

	/**
	 * This method sends a request from the user to the specified entity but is
	 * specific to advanced search .
	 * 
	 * @author Shahir
	 * 
	 * @param entityId
	 *            The long(Integer) ID of the entity that the user wished to join.
	 */

	public static void requestToJoinEntityAdv(long entityId) {

		Entities entity = Entities.findById(entityId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		JsonObject json = new JsonObject();

		for (int i = 0; i < ideaDeveloper.requests.size(); i++) {
			if (ideaDeveloper.requests.get(i).type.equals("JoinEntFromDevToEnt")) {
				if (ideaDeveloper.requests.get(i).ent.equals(entity)) {
					json.addProperty("result",
							"You have already requested to join this entity.");
					renderJSON(json.toString());
					return;
				}
			}
		}

		for (int i = 0; i < ideaDeveloper.joinedEnt.size(); i++) {

			if (ideaDeveloper.joinedEnt.get(i).equals(entity)) {
				json.addProperty("result",
						"You have already joined this entity.");
				renderJSON(json.toString());
				return;
			}

		}

		Request.RequestMe(entity, ideaDeveloper, "JoinEntFromDevToEnt");

		json.addProperty("result", "Request sent.");

		renderJSON(json.toString());
	}
/**
 * create an idea and post it , make it visible to all ideaDevelopers
 * @author : amira
 * @param id
 *    id of the place where the idea will exist
 * @param descr
 *     description of the idea
 * @param title
 *     title of the idea
 * @param whereIdeaExist
 *       String to indicate where the idea will exist
 */
	public static void createpostIdea(long id, String descr, String title,
			String whereIdeaExist) {
		Idea idea = new Idea();
		long ideaDeveloperId = ((IdeaDeveloper) (IdeaDeveloper.find("id=?",
				Security.userid()).fetch().get(0))).id;
		if (whereIdeaExist.equals("topic")) {
			idea = Idea.createIdeaTopic(title, descr, ideaDeveloperId, id);

		}
		if (whereIdeaExist.equals("entity")) {
			idea = Idea.createIdeaEntity(title, descr, ideaDeveloperId, id);
		}
		if (whereIdeaExist.equals("org")) {
			idea = Idea.createIdeaOrg(title, descr, ideaDeveloperId, id);
		}

		idea.postAnIdea();
		JsonObject json = new JsonObject();
		json.addProperty("title", idea.title);
		json.addProperty("description", idea.description);
		json.addProperty("ideaId", idea.id);
		json.addProperty("numberOfVotes", idea.noOfVotes);

		renderJSON(json.toString());
	}
/**
 * it creates an idea and draft it
 * @author : amira
 * @param id
 *  id of where the idea will exist
 * @param descr
 *  description of the idea
 * @param title
 * title of the idea
 * @param whereIdeaExist
 *   String to indicate where the idea will exist
 */
	public static void draftIdea(long id, String descr, String title,
			String whereIdeaExist) {
		Idea idea = new Idea();
		long ideaDeveloperId = ((IdeaDeveloper) (IdeaDeveloper.find("id=?",
				Security.userid()).fetch().get(0))).id;
		if (whereIdeaExist.equals("topic")) {
			idea = Idea.createIdeaTopic(title, descr, ideaDeveloperId, id);

		}
		if (whereIdeaExist.equals("entity")) {
			idea = Idea.createIdeaEntity(title, descr, ideaDeveloperId, id);
		}
		if (whereIdeaExist.equals("org")) {
			idea = Idea.createIdeaOrg(title, descr, ideaDeveloperId, id);
		}

		JsonObject json = new JsonObject();
		json.addProperty("title", idea.title);
		json.addProperty("description", idea.description);
		json.addProperty("ideaId", idea.id);
		json.addProperty("numberOfVotes", idea.noOfVotes);

		renderJSON(json.toString());

	}
/**
 * post a drafted idea , make it visible to all idea developers
 * @author : amira
 * @param ideaId
 *     id of the idea that will be posted
 * @param description
 *      the modified  description
 * @param title
 *  the modified title
 */
	public static void postDraftIdea(long ideaId, String description,
			String title) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		idea.creator.incrementCounter(5);
		idea.description = description;
		idea.title = title;
		idea.save();
		idea.postAnIdea();
		JsonObject json = new JsonObject();
		json.addProperty("ideaDescription", idea.description);
		json.addProperty("ideaId", idea.id);
                json.addProperty("ideaTitle", idea.title);
		renderJSON(json.toString());
	}


        /**
         * modify a draft idea the draft it again
         * @author : amira
         * @param ideaId
         *        id of the idea
         * @param description
         *           the modified description
         * @param title
         *            the modified title
         */
	public static void draftDraftIdea(long ideaId, String description,
			String title) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		idea.description = description;
		idea.title = title;
		idea.save();
		JsonObject json = new JsonObject();
		json.addProperty("ideaDescription", idea.description);
		json.addProperty("ideaId", idea.id);
                json.addProperty("ideaTitle", idea.title);
		renderJSON(json.toString());
	}

	/**
	 * close a specified topic by taking its id
	 * 
	 * @author Sameha
	 * 
	 * @param topicId
	 *            the topic to be closed
	 */
	public static void closeTopic(long topicId) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		topic.closeTopic();

		
		// JsonObject json = new JsonObject();
		if (topic.closed) {
			Log log = new Log("^ closed topic ^");
			log.ids = ideaDeveloper.id + "," + topicId;
			log.types = "developer,topic";
			log.save();

			// json.addProperty("x", "closed Successfully");
		} else {
			// json.addProperty("x", "not closed");
		}

		//
		// renderJSON(json.toString());
		TopicIdeaController.checkAuthorizationToViewTopic(topicId);

	}

	/**
	 * takes the topic's id and re-open this topic again
	 * 
	 * @author Sameha
	 * 
	 * @param topicId
	 *            the topic to be re opened
	 */
	public static void reOpenTopic(long topicId) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		topic.reOpenTopic();
		
		// JsonObject json = new JsonObject();
		if (topic.closed == false) {
			Log log = new Log("^ re-Opened topic ^");
			log.ids = ideaDeveloper.id + "," + topicId;
			log.types = "developer,topic";
			log.save();
			// json.addProperty("x", "reOpened Successfully");
		} else {
			// json.addProperty("x", "still closed");
		}
		// renderJSON(json.toString());
		checkAuthorizationToViewTopic(topicId);
	}

	/**
	 * takes the topicId and promote this topic for execution and save it in the
	 * database
	 * 
	 * @author Sameha
	 * 
	 * @param topicId
	 *            the topic to be promoted
	 */
	public static void promoteTopic(long topicId) {

		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		topic.promoteTopic();
		topic.save();
		
		// JsonObject json = new JsonObject();
		if (topic.promotedForExecution) {
			Log log = new Log("^ promoted topic ^");
			log.ids = ideaDeveloper.id + "," + topicId;
			log.types = "developer,topic";
			log.save();
			// json.addProperty("x", "promoted Successfully");
		} else {
			// json.addProperty("x", "not promoted");
		}
		// renderJSON(json.toString());
		checkAuthorizationToViewTopic(topicId);

	}

	/**
	 * 
	 * A method that adds the rating of the specified idea developer to the
	 * specified topic.
	 * 
	 * @author Shahir
	 * 
	 * @param rate
	 *            The Integer representing actual rating chosen by the user
	 * 
	 * @param topicId
	 *            The long(Integer) representing the ID of the topic that is being rated
	 * 
	 */
	public static void rateTopic(int rate, long topicId) {

		Topic topic = Topic.findById(topicId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		Rate newRating;

		long previous = Rate.count("ideaDeveloper = ? and topic = ?",
				ideaDeveloper, topic);

		if (previous == 0) {
			newRating = new Rate(rate, ideaDeveloper, topic);
		} else {
			newRating = Rate.find("ideaDeveloper = ? and topic = ?",
					ideaDeveloper, topic).first();
			newRating.rating = rate;
		}

		newRating.save();

		JsonObject json = new JsonObject();

		json.addProperty("result", newRating.rating);

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that adds the rating of the specified idea developer to the
	 * specified idea.
	 * 
	 * @author Shahir
	 * 
	 * @param rate
	 *            The Integer representing the actual rating chosen by the user
	 * 
	 * @param ideaId
	 *            The long(Integer) representing the ID of the idea that is being rated
	 * 
	 */
	public static void rateIdea(int rate, long ideaId) {

		Idea idea = Idea.findById(ideaId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		Rate newRating;

		long previous = Rate.count("ideaDeveloper = ? and idea = ?",
				ideaDeveloper, idea);

		if (previous == 0) {
			newRating = new Rate(rate, ideaDeveloper, idea);
		} else {
			newRating = Rate.find("ideaDeveloper = ? and idea = ?",
					ideaDeveloper, idea).first();
			newRating.rating = rate;
		}

		newRating.save();

		JsonObject json = new JsonObject();

		json.addProperty("result", newRating.rating);

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that adds the rating of the specified idea developer to the
	 * specified action plan.
	 * 
	 * @author Shahir
	 * 
	 * @param rate
	 *            The Integer representing the  actual rating chosen by the user
	 * 
	 * @param actionPlanId
	 *            The long(Integer) representing the ID of the action plan that is being rated
	 * 
	 */
	public static void rateActionPlan(int rate, long actionPlanId) {

		ActionPlan actionPlan = ActionPlan.findById(actionPlanId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		Rate newRating;

		long previous = Rate.count("ideaDeveloper = ? and actionPlan = ?",
				ideaDeveloper, actionPlan);

		if (previous == 0) {
			newRating = new Rate(rate, ideaDeveloper, actionPlan);
		} else {
			newRating = Rate.find("ideaDeveloper = ? and actionPlan = ?",
					ideaDeveloper, actionPlan).first();
			newRating.rating = rate;
		}

		newRating.save();

		JsonObject json = new JsonObject();

		json.addProperty("result", newRating.rating);

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that adds the rating of the specified idea developer to the
	 * specified organization.
	 * 
	 * @author Shahir
	 * 
	 * @param rate
	 *            The Integer representing the actual rating chosen by the user
	 * 
	 * @param organizationId
	 *            The long(Integer) representing the ID of the organization that is being rated
	 * 
	 */
	public static void rateOrganization(int rate, long organizationId) {

		Organization organization = Organization.findById(organizationId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		Rate newRating;

		long previous = Rate.count("ideaDeveloper = ? and organization = ?",
				ideaDeveloper, organization);

		if (previous == 0) {
			newRating = new Rate(rate, ideaDeveloper, organization);
		} else {
			newRating = Rate.find("ideaDeveloper = ? and organization = ?",
					ideaDeveloper, organization).first();
			newRating.rating = rate;
		}

		newRating.save();

		JsonObject json = new JsonObject();

		json.addProperty("result", newRating.rating);

		renderJSON(json.toString());

	}

	/**
	 * 
	 * A method that adds the rating of the specified idea developer to the
	 * specified entity.
	 * 
	 * @author Shahir
	 * 
	 * @param rate
	 *            The Integer representing the actual rating chosen by the user
	 * 
	 * @param entityId
	 *            The long(Integer) representing the ID of the entity that is being rated
	 * 
	 */
	public static void rateEntity(int rate, long entityId) {

		Entities entity = Entities.findById(entityId);

		IdeaDeveloper ideaDeveloper = IdeaDeveloper.findById(Security.userid());

		Rate newRating;

		long previous = Rate.count("ideaDeveloper = ? and entity = ?",
				ideaDeveloper, entity);

		if (previous == 0) {
			newRating = new Rate(rate, ideaDeveloper, entity);
		} else {
			newRating = Rate.find("ideaDeveloper = ? and entity = ?",
					ideaDeveloper, entity).first();
			newRating.rating = rate;
		}

		newRating.save();

		JsonObject json = new JsonObject();

		json.addProperty("result", newRating.rating);

		renderJSON(json.toString());

	}

	/**
	 * @autho Zein
	 * adds tag to an idea, topic or an action item
	 * 
	 * @param ID
	 *            id of the object which the tag will be added to
	 * @param name
	 *            name of the tag
	 * @param type
	 *            type of the object the tag is added to, could be an idea , a topic or actionitem
	 */
	public static void addTag(long ID, String name, String type) {
		JsonObject json = new JsonObject();
		IdeaDeveloper creator = (IdeaDeveloper) IdeaDeveloper
		.find("id=?", Security.userid()).fetch().get(0);
		if (type.equalsIgnoreCase("idea")) {
			Idea idea = (Idea) Idea.find("id=?", ID).fetch().get(0);
			if (idea.existingTag(name)) {
				json.addProperty("box", "Already Exists");
			} else {
				idea.addTag(name);
				json.addProperty("box", name + " has been added to "
						+ idea.title);
				Notification.notify("<p><a href=\"http://localhost:9000/topicideacontroller/checkauthorizationtoviewidea?ideaId="+ ID + "\">" + " has just added to idea : " + idea.title +" tag: " + name + "</a></p>", idea.creator, creator, new Date());
			}
		} else if (type.equalsIgnoreCase("topic")) {
			Topic topic = (Topic) Topic.find("id=?", ID).fetch().get(0);
			if (topic.existingTag(name)) {
				json.addProperty("box", "Already Exists");
			} else {
				topic.addTag(name);
				json.addProperty("box", name + " has been added to "
						+ topic.title);
				Notification.notify("<p><a href=\"http://localhost:9000/topicideacontroller/checkauthorizationtoviewtopic?ideaId="+ ID + "\">" + creator.username + " has just added to topic : " + topic.title +" tag: " + name + "</a></p>", topic.creator, creator, new Date());
			}
		} else if (type.equalsIgnoreCase("actionitem")) {
			ActionItem actionitem = (ActionItem) ActionItem.find("id=?", ID)
					.fetch().get(0);
			if (actionitem.existingTag(name)) {
				json.addProperty("box", "Already Exists");
			} else {
				actionitem.addTag(name);
				json.addProperty("box", name + " has been added to "
						+ actionitem.title);
				for (int i = 0; i < actionitem.actionPlan.managers.size(); i++) {
		            Notification.notify("<p><a href=\"http://localhost:9000/actionplancontroller/actionplanorganizer?actionPlanId="+ actionitem.actionPlan.id + "\">" + creator.username + " just commented on action plan of name: "+ actionitem.actionPlan.name + "</a></p>", actionitem.actionPlan.managers.get(i).ideaDeveloper,creator, new Date());

		        }
			}
		}
		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * shows tag of an idea, topic or an action item
	 * 
	 * @param ID
	 *            id of the object from which the tags will be retrieved
	 * @param type
	 *            type of the object the tags are retrieved from, could be an idea , a topic or actionitem
	 */
	public static void showTags(long ID, String type) {
		JsonObject json = new JsonObject();
		String tags = "";
		boolean entered = false;
		if (type.equalsIgnoreCase("idea")) {
			Idea idea = (Idea) Idea.find("id=?", ID).fetch().get(0);
			int i = 0;
			while (i < idea.tags.size()) {
				tags = tags + ((Tag) idea.tags.get(i)).name;
				tags = tags + "$$";
				entered = true;
				i++;
			}
			if (entered) {
				tags = tags.substring(0, tags.length() - 2);
			}
		} else if (type.equalsIgnoreCase("topic")) {
			Topic topic = (Topic) Topic.find("id=?", ID).fetch().get(0);
			int i = 0;
			while (i < topic.tags.size()) {
				tags = tags + ((Tag) topic.tags.get(i)).name;
				tags = tags + "$$";
				entered = true;
				i++;
			}
			if (entered) {
				tags = tags.substring(0, tags.length() - 2);
			}
		} else if (type.equalsIgnoreCase("actionitem")) {
			ActionItem actionitem = (ActionItem) ActionItem.find("id=?", ID).fetch().get(0);
			int i = 0;
			while (i < actionitem.tags.size()) {
				tags = tags + ((Tag) actionitem.tags.get(i)).name;
				tags = tags + "$$";
				entered = true;
				i++;
			}
			if (entered) {
				tags = tags.substring(0, tags.length() - 2);
			}
		}
		json.addProperty("box", tags);
		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * removes tag from an idea, topic or an action item
	 * 
	 * @param ID
	 *            id of the object from which the tag will be removed
	 * @param name
	 *            name of the tag
	 * @param type
	 *            type of the object from which the tag is removed, could be an idea , a topic or actionitem
	 */
	public static void removeTag(String name, long ID, String type) {
		JsonObject json = new JsonObject();
		if (type.equalsIgnoreCase("idea")) {
			Idea idea = (Idea) Idea.find("id=?", ID).fetch().get(0);
			idea.removeTag(name);
			json.addProperty("box", name + " has been deleted from "
					+ idea.title);
		} else if (type.equalsIgnoreCase("topic")) {
			Topic topic = (Topic) Topic.find("id=?", ID).fetch().get(0);
			topic.removeTag(name);
			json.addProperty("box", name + " has been deleted from "
					+ topic.title);
		} else if (type.equalsIgnoreCase("actionitem")) {
			ActionItem actionitem = (ActionItem) ActionItem.find("id=?", ID).fetch().get(0);
			actionitem.removeTag(name);
			json.addProperty("box", name + " has been deleted from "
					+ actionitem.title);
		}

		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * adds a comment to an idea or an actionplan
	 * 
	 * @param body
	 *            body of the comment to be added
	 * @param ID
	 *            id of the object which the tag will be added to
	 * @param type
	 *            type of the object the comment is added to, could be an idea or actionplan
	 */
	public static void addComment(String body, long ID, String type) {
		JsonObject json = new JsonObject();
		IdeaDeveloper creator = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		if (type.equalsIgnoreCase("idea")) {
			Idea newIdea = (Idea) Idea.find("id=?", ID).fetch().get(0);
			Comment comment = Comment.create(creator, newIdea, body);
			comment.save();
			json.addProperty("box", "Comment is added to Idea: "
					+ newIdea.title + "!id#" + comment.id);
		} else if (type.equalsIgnoreCase("actionplan")) {
			ActionPlan newActionPlan = (ActionPlan) ActionPlan.find("id=?", ID)
					.fetch().get(0);
			Comment comment = Comment.create(creator, newActionPlan, body);
			comment.save();
			json.addProperty("box", "Comment is added to ActionPlan: "
					+ newActionPlan.name);
		}

		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * retrieves all comments of an idea or an actionplan
	 * 
	 * @param ID
	 *            id of the idea from which the comments will be retrieved
	 */
	public static void showIdeaComments(long ID) {
		Idea idea = (Idea) Idea.find("id=?", ID).fetch().get(0);
		List<String> comments = new LinkedList<String>();
		IdeaDeveloper User = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		boolean userAuthorized = false;
		boolean owner = true;
		
		if (idea.ideaOrg != null) {
			if (IdeaDeveloper.canLeadOrganization(User, idea.ideaOrg)) {
				userAuthorized = true;
			}
		} else if (idea.ideaEnt != null) {
			if (IdeaDeveloper.canLeadEntity(User, idea.ideaEnt)) {
				userAuthorized = true;
			}
		} else if (idea.ideaTopic != null) {
			if (IdeaDeveloper.canLeadTopic(User, idea.ideaTopic)) {
				userAuthorized = true;
			}
		}

		for (int i = 0; i < idea.comments.size(); i++) {
			if (Security.userid() != idea.comments.get(i).creator.id){
				owner = false;
			}
			if(userAuthorized || owner){
				comments.add(idea.comments.get(i).body + "!id#"
						+ idea.comments.get(i).creator.username + "!id#"
						+ idea.comments.get(i).creator.id + "!id#"
						+ idea.comments.get(i).id + "!crtr#" + "CanDelete");
			} else {
				comments.add(idea.comments.get(i).body + "!id#"
						+ idea.comments.get(i).creator.username + "!id#"
						+ idea.comments.get(i).creator.id + "!id#"
						+ idea.comments.get(i).id + "!crtr#" + "NoButton");
			}
			owner = true;
		}

		renderJSON(comments);
	}
	
	/**
	 * @author Zein
	 * retrieves all comments of an idea or an actionplan
	 * 
	 * @param ID
	 *            id of the idea from which the comments will be retrieved
	 */
	public static void showActionPlanComments(long ID) {
		ActionPlan actionplan = (ActionPlan) ActionPlan.find("id=?", ID)
				.fetch().get(0);
		List<String> comments = new LinkedList<String>();
		IdeaDeveloper User = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		
		boolean userAuthorized = false;
		boolean owner = true;
		
		for(int i = 0; i < actionplan.managers.size(); i ++){
			if (actionplan.managers.get(i).equals(User)) {
				userAuthorized = true;
				break;
			} 
		}

		for (int i = 0; i < actionplan.comments.size(); i++) {
			if (Security.userid() != actionplan.comments.get(i).creator.id){
				owner = false;
			}
			if(userAuthorized || owner){
				comments.add(actionplan.comments.get(i).body + "!id#"
						+ actionplan.comments.get(i).creator.username + "!id#"
						+ actionplan.comments.get(i).creator.id + "!id#"
						+ actionplan.comments.get(i).id + "!crtr#" + "CanDelete");
			} else {
				comments.add(actionplan.comments.get(i).body + "!id#"
						+ actionplan.comments.get(i).creator.username + "!id#"
						+ actionplan.comments.get(i).creator.id + "!id#"
						+ actionplan.comments.get(i).id + "!crtr#" + "NoButton");
			}
			owner = true;
		}
		renderJSON(comments);
	}

	/**
	 * @author Zein
	 * deletes comment
	 * 
	 * @param ID
	 *            id of the comment
	 */
	public static void removeComment(long ID) {
		JsonObject json = new JsonObject();
		Comment comment = ((Comment) (Comment.find("id=?", ID).fetch().get(0)));
		long id = comment.id;
		comment.delete2();
		json.addProperty("box", comment.body + " deleted !");
		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * retrieves all duplicate ideas in a specific topic, entity or organization
	 * 
	 * @param ID
	 *            id of the object from which the duplicate ideas will be retrieved
	 * @param type
	 *            type of the object from which the duplicate ideas will be retrieved
	 */
	public static void showDuplicateIdeas(long ID, String type) {
		JsonObject json = new JsonObject();
		String duplicateIdeas = "";
		boolean entered = false;
		boolean entered2 = false;
		if (type.equalsIgnoreCase("topic")) {
			Topic topic = ((Topic) (Topic.find("id = ?", ID).fetch().get(0)));
			for (int i = 0; i < topic.ideas.size(); i++) {
				if (!topic.ideas.get(i).duplicates.isEmpty()) {
					duplicateIdeas += topic.ideas.get(i).title;
					duplicateIdeas += "!id#" + topic.ideas.get(i).id;
					duplicateIdeas += "!id#" + topic.ideas.get(i).description;
					duplicateIdeas += "*$";
					for (int j = 0; j < topic.ideas.get(i).duplicates.size(); j++) {
						duplicateIdeas += topic.ideas.get(i).duplicates.get(j).title;
						duplicateIdeas += "!id#"
								+ topic.ideas.get(i).duplicates.get(j).id;
						duplicateIdeas += "!id#"
								+ topic.ideas.get(i).duplicates.get(j).description;
						duplicateIdeas += "$*";
						entered2 = true;
					}
					if (entered2) {
						duplicateIdeas = duplicateIdeas.substring(0,
								duplicateIdeas.length() - 2);
					}
					entered = true;
					duplicateIdeas += "$$";
				}
			}
		} else if (type.equalsIgnoreCase("organization")) {
			Organization organization = ((Organization) (Organization.find(
					"id = ?", ID).fetch().get(0)));
			for (int i = 0; i < organization.ideas.size(); i++) {
				if (!organization.ideas.get(i).duplicates.isEmpty()) {
					duplicateIdeas += organization.ideas.get(i).title;
					duplicateIdeas += "!id#" + organization.ideas.get(i).id;
					duplicateIdeas += "!id#"
							+ organization.ideas.get(i).description;
					duplicateIdeas += "*$";
					for (int j = 0; j < organization.ideas.get(i).duplicates
							.size(); j++) {
						duplicateIdeas += organization.ideas.get(i).duplicates
								.get(j).title;
						duplicateIdeas += "!id#"
								+ organization.ideas.get(i).duplicates.get(j).id;
						duplicateIdeas += "!id#"
								+ organization.ideas.get(i).duplicates.get(j).description;
						duplicateIdeas += "$*";
						entered2 = true;
					}
					if (entered2) {
						duplicateIdeas = duplicateIdeas.substring(0,
								duplicateIdeas.length() - 2);
					}
					entered = true;
					duplicateIdeas += "$$";
				}
			}
		} else if (type.equalsIgnoreCase("entity")) {
			Entities entity = ((Entities) (Entities.find("id = ?", ID).fetch()
					.get(0)));
			for (int i = 0; i < entity.ideas.size(); i++) {
				if (!entity.ideas.get(i).duplicates.isEmpty()) {
					duplicateIdeas += entity.ideas.get(i).title;
					duplicateIdeas += "!id#" + entity.ideas.get(i).id;
					duplicateIdeas += "!id#" + entity.ideas.get(i).description;
					duplicateIdeas += "*$";
					for (int j = 0; j < entity.ideas.get(i).duplicates.size(); j++) {
						duplicateIdeas += entity.ideas.get(i).duplicates.get(j).title;
						duplicateIdeas += "!id#"
								+ entity.ideas.get(i).duplicates.get(j).id;
						duplicateIdeas += "!id#"
								+ entity.ideas.get(i).duplicates.get(j).description;
						duplicateIdeas += "$*";
						entered2 = true;
					}
					if (entered2) {
						duplicateIdeas = duplicateIdeas.substring(0,
								duplicateIdeas.length() - 2);
					}
					entered = true;
					duplicateIdeas += "$$";
				}
			}
		}
		if (entered) {
			duplicateIdeas = duplicateIdeas.substring(0,
					duplicateIdeas.length() - 2);
		}
		json.addProperty("box", duplicateIdeas);
		renderJSON(json.toString());
	}
	
	/**
	 * @author Zein
	 * sends a notification to the duplicate idea owner
	 * 
	 * @param ID
	 *            id of the duplicated idea
	 * @param ID
	 *            id of the duplicate idea
	 */
	public static void notifyDuplicateOwner(long id, long id2) {
		Idea source = (Idea) Idea.find("id=?", id).fetch().get(0);
		Idea duplicate = (Idea) Idea.find("id=?", id2).fetch().get(0);
		IdeaDeveloper merger = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		Notification.notify(" decided to remove your idea of title "
				+ duplicate.title + " , since it is a duplicate of idea "
				+ source.title
				+ ". To review your idea's description check your mail ",
				duplicate.creator, merger, new Date());
		merger.sendEMail(
				duplicate.creator.eMail,
				"Your murger duplicate idea",
				"Dear "
						+ duplicate.creator.fullName
						+ "\n"
						+ "Following, is the descripton of the idea that has been merged with the idea of title '"
						+ source.title + "' :" + "\n" + duplicate.description
						+ "\n" + "\n" + "Regards," + "\n" + "\n"
						+ merger.fullName);
	}

	/**
	 * @author Zein
	 * removes the duplicate ideas from the duplicated ideas and the duplicated idea from all of its duplicates
	 * 
	 * @param ID
	 *            id of the duplicated idea
	 */
	public static void removeDuplicatesRelation(long ID) {
		JsonObject json = new JsonObject();
		Idea source = (Idea) Idea.find("id=?", ID).fetch().get(0);
		int i = 0;
		while (!source.duplicates.isEmpty()) {
			source.duplicates.get(i).duplicatesOf.remove(source);
			source.duplicates.get(i).save();
			source.duplicates.remove(i);
			source.save();
		}
	}

	public static void RestrictOrganizerTopic() {
		IdeaDeveloper i1 = new IdeaDeveloper();
		IdeaDeveloper i2 = new IdeaDeveloper();
		IdeaDeveloper i3 = new IdeaDeveloper();
		Organization o = new Organization();
		OrganizationLead OL = new OrganizationLead();
		Organizer z1 = new Organizer();
		Organizer z2 = new Organizer();
		Organizer z3 = new Organizer();
		Entities e1 = new Entities();
		Entities e2 = new Entities();
		Topic t = new Topic();

		i1.username = "omar1";
		i1.fullName = "omar1";
		i1.eMail = "omar1";
		i1.dateOfBirth = "omar1";
		i1.password = "omar1";
		i1.passwordHash = "omar1";
		i1.address = "omar1";
		i1.save();

		i2.username = "gebna1";
		i2.fullName = "gebna1";
		i2.eMail = "gebna1";
		i2.dateOfBirth = "gebna1";
		i2.password = "gebna1";
		i2.passwordHash = "gebna1";
		i2.address = "gebna1";
		i2.save();

		i3.username = "Alien1";
		i3.fullName = "Alien1";
		i3.eMail = "Alien1";
		i3.dateOfBirth = "Alien1";
		i3.password = "Alien1";
		i3.passwordHash = "Alien1";
		i3.address = "Alien1";
		i3.save();

		OL.ideaDeveloper = i1;
		o.name = "organization dddd";
		OL.save();
		o.creator = OL;
		o.managers.add(OL);

		o.liesIn.add(e1);
		o.liesIn.add(e2);
		OL.manages.add(o);
		z1.ideaDeveloper = i2;
		z2.ideaDeveloper = i1;
		z3.ideaDeveloper = i3;

		z1.manages.add(e1);
		z1.manages.add(e2);
		z2.manages.add(e1);
		z2.manages.add(e2);
		z2.managedTopics.add(t);
		z3.managedTopics.add(t);

		e1.liesIn = o;
		e1.name = "Eentity11";
		e1.managers.add(z1);
		e1.managers.add(z2);

		e2.liesIn = o;
		e2.name = "Eentity22";
		e2.managers.add(z1);
		e2.managers.add(z2);
		t.hidden = false;
		t.title = "topic";
		t.description = "wazzzaaa";
		t.dateOfDraftingPosting = new java.util.Date();
		t.managers.add(z1);
		t.topicOrg = o;
		// t.managers.add(z3);
		t.topicEnt = e1;
		t.managers.add(z2);
		z1.managedTopics.add(t);
		z2.managedTopics.add(t);
		o.topics.add(t);
		z3.managedTopics.add(t);
		o.save();

		z1.save();
		z2.save();
		z3.save();
		e2.save();
		t.save();
		e1.save();

		String leadID = OL.id.toString();
		String topicID = t.id.toString();
		String entityID = e1.id.toString();
		render(topicID, leadID, entityID);
	}

	public static void getOrganizersTopic(long topicID) {
		JsonObject json = new JsonObject();
		String s = "*";
		try {
			Topic t = Topic.find("id =?", topicID).first();
			for (int i = 0; i < t.managers.size(); i++) {
				if (!s.contains(t.managers.get(i).ideaDeveloper.username)) {
					s += t.managers.get(i).ideaDeveloper.username + "*";
				}
			}
		} catch (Exception e) {
			json.addProperty("res", "matrunesh");
		}
		json.addProperty("res", s);

		renderJSON(json.toString());
	}

	/**
	 * restricts an organizer to a topic by removing this organizer from
	 * organizing any other entity or topic in this organization
	 * 
	 * @author Omar el alfy
	 * @param topicID
	 *            topic id to be restricted to
	 * @param OrganizerName
	 *            organizer username that is being restricted
	 */
	public static void resOrganizersTopic(long topicID, String OrganizerName) {
		JsonObject json = new JsonObject();
		String result = "done";
		Topic topic = Topic.find("id =?", topicID).first();
		Organizer organizer = new Organizer();
		for (int i = 0; i < Organizer.findAll().size(); i++) {
			if ((((Organizer) Organizer.findAll().get(i)).ideaDeveloper.username)
					.equals(OrganizerName)) {
				organizer = (Organizer) Organizer.findAll().get(i);
				break;
			}
		}
		json.addProperty("res",OrganizationLead.restrictAccessTopic(organizer, topic));
		Notification.notify("has restricted you to topic : "+topic.title, organizer.ideaDeveloper,(IdeaDeveloper) IdeaDeveloper.find("username=?", Security.connected()).first(),new Date());
		renderJSON(json.toString());
	}

	/**
	 * check the authorization to view the topic and render the topic
	 * @author  : amira
	 * @param topicId
	 *            the topic user wants to view
         *
	 */
	public static void checkAuthorizationToViewTopic(long topicId) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);

		IdeaDeveloper developer = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);
		String ideaDeveloperName = developer.username;
		Long ideaDeveloperId = developer.id;
		String topicTitle = topic.title;
		String topicDescription = topic.description;
		String type = "";
		String page = "1";
		String total = "0";
		String Author = topic.creator.username;
		List topicRelations = TopicRelation.find(
				"firstTopic=? or secondTopic=? ", topicId, topicId).fetch();

		boolean isOrganizer = IdeaDeveloper.canLeadTopic(developer, topic);
		boolean isOrganizerORIsCreator = (topic.creator== developer) || isOrganizer;
		boolean topicisLocked = topic.locked;

		List topics;
		List topicsNames = new ArrayList<String>();
		List toBeDeleted = new ArrayList<String>();

		int canLeadOrg = 0;

		for (int i = 0; i < topicRelations.size(); i++) {
			TopicRelation y = (TopicRelation) topicRelations.get(i);
			Topic one = Topic.findById(y.firstTopic);
			Topic two = Topic.findById(y.secondTopic);

			toBeDeleted.add(one.title + " " + y.toString() + " " + two.title);
		}
		List firststopics = new ArrayList<Topic>();
		List secondstopics = new ArrayList<Topic>();
		List relnames = new ArrayList<String>();
		for (int i = 0; i < topicRelations.size(); i++) {
			TopicRelation y = (TopicRelation) topicRelations.get(i);
			Topic one = Topic.findById(y.firstTopic);
			//Topic two = Topic.findById(y.secondTopic);

			firststopics.add(one);
		}
		for (int i = 0; i < topicRelations.size(); i++) {
			TopicRelation y = (TopicRelation) topicRelations.get(i);
			//Topic one = Topic.findById(y.firstTopic);
			Topic two = Topic.findById(y.secondTopic);

			secondstopics.add(two);
		}
		for (int i = 0; i < topicRelations.size(); i++) {
			TopicRelation y = (TopicRelation) topicRelations.get(i);
			//Topic one = Topic.findById(y.firstTopic);
			

			relnames.add(y.relationName);
		}
		

		Organization org = topic.orgWhereTopicExist();
		for (int i = 0; i < org.topics.size(); i++) {
			if (!org.topics.get(i).equals(topic))
				topicsNames.add(org.topics.get(i).title);
		}
		for (int i = 0; i < org.liesIn.size(); i++) {
			for (int j = 0; j < org.liesIn.get(i).topics.size(); j++) {
				if (!org.liesIn.get(i).topics.get(j).equals(topic))
					topicsNames.add(org.liesIn.get(i).topics.get(j).title);
			}
		}
		/*
		 * if (topic.topicOrg != null || topic.topicEnt != null) { if
		 * (topic.topicOrg != null) { topics = topic.topicOrg.topics; } else {
		 * topics = topic.topicEnt.liesIn.topics;
		 * 
		 * }
		 * 
		 * for (int i = 0; i < topic.topicOrg.liesIn.size(); i++) { for (int j =
		 * 0; j < topic.topicOrg.liesIn.size(); j++) {
		 * topics.addAll(topic.topicOrg.liesIn.get(i).topics); } }
		 * 
		 * 
		 * for (int i = 0; i < topics.size(); i++) { Topic x = (Topic)
		 * topics.get(0); topicsNames.add(x.title); }
		 * 
		 * }
		 * 
		 * /* if (topic.topicOrg != null || topic.topicEnt != null) { if
		 * (topic.topicOrg != null) { topics = topic.topicOrg.topics; } else {
		 * topics = topic.topicEnt.liesIn.topics; }
		 * 
		 * for (int i = 0; i < topic.topicOrg.liesIn.size(); i++) { for (int j =
		 * 0; j < topic.topicOrg.liesIn.size(); j++) {
		 * topics.addAll(topic.topicOrg.liesIn.get(i).topics); } }
		 * 
		 * 
		 * for (int i = 0; i < topics.size(); i++) { Topic x = (Topic)
		 * topics.get(0); topicsNames.add(x.title); } }
		 */
        Organization o=topic.orgWhereTopicExist();
        if(o.deactivated== true){
        	type="NotjoinedIdeaDeveloper";
        }else{
		if (IdeaDeveloper.canLeadTopic(developer, topic)) {
			if (topic.closed) {
				type = "OrgOrOrgLeadCloseTopic";
			} else {
				if (topic.promotedForExecution) {
					type = "OrgOrOrgLeadPromoteTopic";
				} else {

					type = "OrgOrOrgLeadOpenTopic";
					// types="NotjoinedIdeaDeveloper";
                    
				}
			}
		} else {
			if (!IdeaDeveloper.isMemberOrganization(developer,
					topic.orgWhereTopicExist())
					|| topic.closed || topic.promotedForExecution) {
				type = "NotjoinedIdeaDeveloper";
			} else {
				type = "joinedIdeaDeveloper";
			}
		}

		try {
			Organization organizationTopic = Organization.find("name=?",
					BrowseController.getTopicOrganization(topicId)).first();
			if (IdeaDeveloper.canLeadOrganization(developer, organizationTopic)) {
				canLeadOrg = 1;
			}
		} catch (Exception e) {
			canLeadOrg = 0;
		}
		}
		int numberOfViews = topic.incrementViews();
                int share=0;
                if(IdeaDeveloper.isMemberTopic(developer, topic)){
                    share=1;
                }
       
		render("TopicIdeaController/TopicView.html", topicId, ideaDeveloperId,
				ideaDeveloperName, topicDescription, topicTitle,
				topicRelations, isOrganizerORIsCreator, topicsNames, type,
				page, total, toBeDeleted, isOrganizer, topicisLocked,
				numberOfViews, topic, canLeadOrg, Author,relnames,firststopics,secondstopics,share);
	}

	/**
	 * checks if the user authorized to view idea and render the idea
	 *  @ author  :amira
	 * @param ideaId
	 *            the idea user wants to view
	 */
	public static void checkAuthorizationToViewIdea(long ideaId) {
		IdeaDeveloper member = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", Security.userid()).fetch().get(0);

		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);

		long ideaDeveloperId = member.id;
		String ideaDeveloperName = member.username;
		String ideaTitle = idea.title;
		String ideaDescription = idea.description;
		String creatorName = idea.creator.username;
		long creatorId = idea.creator.id;
		int numberOfVotes = idea.noOfVotes;
		int voted = 0;
		int report = 0;
		int creator = 0;
		int promote = 0;
		String reportIdea = "";
		String type = "";
		String status = "";
		long actionPlan = 0;

		Date date = idea.dateOfDraftingPosting;
        Organization o=idea.orgWhereIdeaExist();
        if(o.deactivated==true){
        	type = "NotjoinedIdeaDeveloper";
			status = " the organization is deactivated";
        }else{
		if (idea.ideaOrg != null) {
			if (IdeaDeveloper.canLeadOrganization(member, idea.ideaOrg)) {
				type = "OrgOpen";
				status = "";
			} else {
				if (IdeaDeveloper.isMemberOrganization(member, idea.ideaOrg)) {
					type = "joinedIdeaDeveloper";
					status = "";
				} else {
					type = "NotjoinedIdeaDeveloper";
					status = "you have to join the organization";
				}
			}
		}
		if (idea.ideaEnt != null) {
			if (IdeaDeveloper.canLeadEntity(member, idea.ideaEnt)) {
				type = "OrgOpen";
				status = "";
			} else {
				if (IdeaDeveloper.isMemberOrganization(member,
						idea.ideaEnt.liesIn)) {
					type = "joinedIdeaDeveloper";
					status = "";
				} else {
					type = "NotjoinedIdeaDeveloper";
					status = "you have to join the organization";
				}
			}
		}
		if (idea.ideaTopic != null) {
			if (!IdeaDeveloper.isMemberIdea(member, idea)
					|| idea.ideaTopic.closed == true
					|| idea.ideaTopic.promotedForExecution == true) {
				if (idea.ideaTopic.closed) {
					type = "NotjoinedIdeaDeveloper";
					status = "the topic is closed";
				} else {
					if (idea.ideaTopic.promotedForExecution) {
						type = "NotjoinedIdeaDeveloper";
						status = "the topic is promoted";
					} else {

						type = "NotjoinedIdeaDeveloper";
						status = "you have to join the organization";
					}
				}
			} else {
				if (IdeaDeveloper.canLeadTopic(member, idea.ideaTopic)) {
					type = "OrgOpen";
					status = "";
				} else {
					type = "joinedIdeaDeveloper";
					status = "";
				}
			}

		}
        }
		if (idea.vote.contains(member)) {
			voted = 1;
		} else {
			voted = 0;
		}

		if (idea.spam.contains(member)) {
			report = 1;
		} else {
			report = 0;
		}
		if (idea.promotedForExecution == true) {
			promote = 1;
		} else {
			promote = 0;
		}
		if (idea.creator.equals(member)) {
			creator = 1;
		} else {
			creator = 0;
		}

		if (idea.spam.size() > 0) {
			reportIdea = idea.spam.size() + "This idea is reported as spam";
		}
		if (idea.ideaPlan != null) {
			actionPlan = idea.ideaPlan.id;
		}
		int numberOfViews = idea.incrementNumberOfViews();
                int share=0;
                if(IdeaDeveloper.isMemberIdea(member, idea)){
                    share=1;
                }
		render("TopicIdeaController/IdeaView.html", ideaId, ideaTitle,
				ideaDescription, ideaDeveloperName, ideaDeveloperId,
				numberOfVotes, report, promote, creator, voted, type,

				creatorName, creatorId, status, reportIdea, date,
				numberOfViews, actionPlan, idea,share);

	}

	/**
	 * takes id of topic and retrieves the idea developer and topic
	 * corresponding to these ids and implement the followCheck method and then
	 * sends to the topic view the results of the followCheck
	 * 
	 * @author nataly.wadie
	 * @param topicId
	 *            id of the topic that the idea developer wants to follow
	 */

	public static void canFollowTopic(long topicId) {
		Topic topic = Topic.findById(topicId);
		String followerName = Security.connected();
		IdeaDeveloper follower = (IdeaDeveloper) IdeaDeveloper
				.find("username=?", followerName).fetch().get(0);

		JsonObject checkFollow = new JsonObject();
		if (!Topic.followCheck(follower, topic)) {
			checkFollow.addProperty("followTopic", "can follow");
			renderJSON(checkFollow.toString());
		}
		if (Topic.followCheck(follower, topic)) {
			checkFollow
					.addProperty("followTopic", "you are already a follower");
			renderJSON(checkFollow.toString());
		}
	}

	/**
	 * takes id of topic and gets the object corresponding to these ids and
	 * implements followCheck then followTopic methods and sends the results to
	 * the topic view
	 * 
	 * @author nataly.wadie
	 * @param topicId
	 *            id of topic that the idea developer wants to follow
	 */

	public static void followTopic(long topicId) {
		String followerName = Security.connected();
		IdeaDeveloper follower = (IdeaDeveloper) IdeaDeveloper
				.find("username=?", followerName).fetch().get(0);
		Topic topic = Topic.findById(topicId);

		JsonObject followTopic = new JsonObject();
		if (!Topic.followCheck(follower, topic)) {
			Topic.followTopic(follower, topic);
		}
		followTopic.addProperty("followTopic", "successfully followed");
		renderJSON(followTopic.toString());
	}

	/**
	 * takes topic id and retrieves the idea developer and topic and makes sure
	 * that the user is already a follower then he'll be removed from the
	 * followers list
	 * 
	 * @author nataly.wadie
	 * @param topicId
	 *            the topic that is going to be unfollowed by the user
	 */

	public static void unfollowTopic(long topicId) {
		String followerName = Security.connected();
		IdeaDeveloper follower = (IdeaDeveloper) IdeaDeveloper
				.find("username=?", followerName).fetch().get(0);
		Topic topic = Topic.findById(topicId);

		JsonObject unfollowTopic = new JsonObject();
		if (Topic.followCheck(follower, topic)) {
			Topic.unfollowTopic(follower, topic);
		}
		unfollowTopic.addProperty("unfollowTopic", "successfully unfollowed");
		renderJSON(unfollowTopic.toString());
	}

	/**
	 * takes the idea's id and the ideadeveloper's id and promote this idea for
	 * execution
	 * 
	 * @author Sameha
	 * 
	 * @param ideaId
	 *            idea's id
	 * @param ideaDeveloperId
	 *            idea developer's Id
	 */
	public static void promoteIdea(long ideaId, long ideaDeveloperId) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", ideaDeveloperId).fetch().get(0);
		idea.promoteIdea();

		JsonObject json = new JsonObject();
		if (idea.promotedForExecution) {
			if (idea.ideaTopic != null) {
				for (int i = 0; i < idea.ideaTopic.followed.size(); i++) {
                                    if(!idea.ideaTopic.followed.get(i).equals(ideaDeveloper))
                                    {
                                        Notification.notify("Idea " + idea.title
							+ " has been promoted for execution.",
							idea.ideaTopic.followed.get(i), ideaDeveloper,
							new Date());}

				}
				
			}
			if (idea.ideaEnt != null) {
				for (int i = 0; i < idea.ideaEnt.followed.size(); i++) {
                                      if(!idea.ideaEnt.followed.get(i).equals(ideaDeveloper))
                                      {
                                          Notification.notify("Idea " + idea.title
							+ " has been promoted for execution.",
							idea.ideaEnt.followed.get(i), ideaDeveloper,
							new Date());}

				}
				
			}
			if (idea.ideaOrg != null) {
				for (int i = 0; i < idea.ideaOrg.followed.size(); i++) {
                                    if(!idea.ideaOrg.followed.get(i).equals(ideaDeveloper))
                                    {
                                         Notification.notify("Idea " + idea.title
							+ " has been promoted for execution.",
							idea.ideaOrg.followed.get(i), ideaDeveloper,
							new Date());}

				}
				
			}

			idea.creator.incrementCounter(15);
			Log log = new Log("^ promoted idea ^");
			log.ids = ideaDeveloperId + "," + ideaId;
			log.types = "developer,idea";
			log.save();
			json.addProperty("x", "promoted Successfully");
		} else {
			json.addProperty("x", "not promoted");
		}
		renderJSON(json.toString());

	}

	/**
	 * takes the idea's id and the ideadeveloper's id and demote this idea from
	 * execution
	 * 
	 * @author Sameha
	 * 
	 * @param ideaId
	 *            idea's id
	 * @param ideaDeveloperId
	 *            idea developer's Id
	 */
	public static void demoteIdea(long ideaId, long ideaDeveloperId) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
				.find("id=?", ideaDeveloperId).fetch().get(0);
		idea.demoteIdea();
		int numberOfPromotedIdeas = 0;
		JsonObject json = new JsonObject();
		if (!idea.promotedForExecution) {
			if (idea.ideaTopic != null) {
				for (int i = 0; i < idea.ideaTopic.followed.size(); i++) {
                                    if(!idea.ideaTopic.followed.get(i).equals(ideaDeveloper))
                                    {
					Notification.notify("Idea " + idea.title
							+ " has been demoted from execution.",
							idea.ideaTopic.followed.get(i), ideaDeveloper,
							new Date());}

				}
				
				numberOfPromotedIdeas = Idea
						.find("ideaTopic=? and promotedForExecution=?",
								idea.ideaTopic, true).fetch().size();
			}
			if (idea.ideaEnt != null) {
				for (int i = 0; i < idea.ideaEnt.followed.size(); i++) {
                                    if(!idea.ideaEnt.followed.get(i).equals(ideaDeveloper))
                                    {
					Notification.notify("Idea " + idea.title
							+ " has been demoted from execution.",
							idea.ideaEnt.followed.get(i), ideaDeveloper,
							new Date());}

				}
				
			}
			if (idea.ideaOrg != null) {
				for (int i = 0; i < idea.ideaOrg.followed.size(); i++) {
                                    if(!idea.ideaOrg.followed.get(i).equals(ideaDeveloper))
                                    {
					Notification.notify("Idea " + idea.title
							+ " has been demoted from execution.",
							idea.ideaOrg.followed.get(i), ideaDeveloper,
							new Date()); }

				}
				
			}
			Log log = new Log("^ demoted idea ^");
			log.ids = ideaDeveloperId + "," + ideaId;
			log.types = "developer,idea";
			log.save();
			json.addProperty("x", "demoted Successfully");
			idea.creator.decrementCounter(15);
		} else {
			json.addProperty("x", "not demoted");
		}
		json.addProperty("numberOfPromotedIdeas", numberOfPromotedIdeas);
		renderJSON(json.toString());

	}

	/**
	 * delete the relation between two topics and returns a confirmation message
	 * 
	 * @author XtarX
	 * @param relationId this is the id of the relation
	 */
	public static void deleteTopicRelation(Long relationId) {
		JsonObject deleteResponse = new JsonObject();
		deleteResponse.addProperty("res",
				TopicRelation.DelteRelationsTopics(relationId));
		renderJSON(deleteResponse.toString());
	}
        /**
	 * lock or unlock relation depending on the type if lock it will lock the
	 * topic from being in a relataion,else it will unlock the topic thus can be
	 * in relation with another topics
	 * @author mohamed tarek
	 * @param topicId
	 * the topic to be locked/unlocked id
	 * @param type
	 * the type lock or unlock the topic
	 * @return void
	 */
	public static void lockOrUnlockTopic(Long topicId, String type) {
		JsonObject lockorUnlockResponse = new JsonObject();

		if (type.equals("lock")) {
			lockorUnlockResponse.addProperty("res", Topic.lockTopic(topicId));
			renderJSON(lockorUnlockResponse.toString());

		} else {
			lockorUnlockResponse.addProperty("res", Topic.unlockTopic(topicId));
			renderJSON(lockorUnlockResponse.toString());
		}

	}

	/**
	 * deletes topic
	 * @ author :amira
	 * @param topicId
	 *            the id of topic to be deleted
	 */
	public static void deleteTopic(long topicId) {
		Topic topic = (Topic) Topic.find("id=?", topicId).fetch().get(0);

		long id = 0;
		String type = "";
		String orgName = "";
		if (topic.topicOrg != null) {
			type = "org";
			orgName = topic.topicOrg.name;
		}
		if (topic.topicEnt != null) {
			type = "entity";
			id = topic.topicEnt.id;
		}
		topic.delete2();
		if (Topic.find("id=?", topicId).fetch().isEmpty()) {
			if (type.equals("entity")) {
				Application.EntityView(id);
			} else {
				Application.OrganizationView(orgName);
			}
		}
	}

	/**
	 * report idea or comment as spam
	 * @ author : amira
	 * @param id
	 *            id of what to be reported
	 * @param ideaDeveloperId
	 *            the user reporting  as spam
	 * @param type
	 *            string to indicate  what to be reported an idea or comment
	 */
	public static void reportAsSpam(long id, long ideaDeveloperId, String type) {
		if (type.equalsIgnoreCase("idea")) {
			Idea idea = (Idea) Idea.find("id=?", id).fetch().get(0);
			idea.reportAsSpam(ideaDeveloperId);
		} else {
			Comment comment = (Comment) Comment.find("id=?", id).fetch().get(0);
			comment.reportAsSpam(ideaDeveloperId);
		}

	}

	/**
	 * Deletes idea
	 * @ author : amira
	 * @param ideaId
	 *            idea to be deleted
	 * @param aloneOrNot
	 *            alone in its own view or in another view
	 */
	public static void deleteIdea(long ideaId, String aloneOrNot) {
		Idea idea = (Idea) Idea.find("id=?", ideaId).fetch().get(0);
		if (!(idea.spam.size() == 0)) {
			idea.creator.decrementCounter(10);
		}
		long id = 0;
		String type = "";
		String orgName = "";
		if (idea.ideaTopic != null) {
			id = idea.ideaTopic.id;
			type = "topic";
		}
		if (idea.ideaEnt != null) {
			id = idea.ideaEnt.id;
			type = "entity";
		}
		if (idea.ideaOrg != null) {
			type = "org";
			orgName = idea.ideaOrg.name;
		}
		idea.delete2();

		if (aloneOrNot.equalsIgnoreCase("alone")) {
			if (Idea.find("id=?", ideaId).fetch().isEmpty()) {
				if (type.equals("topic")) {
					TopicIdeaController.checkAuthorizationToViewTopic(id);
				}
				if (type.equals("entity")) {
					Application.EntityView(id);
				}
				if (type.equals("org")) {
					Application.OrganizationView(orgName);
				}
			}
		} else {
			JsonObject json = new JsonObject();
			json.addProperty("x", Idea.find("id=?", ideaId).fetch().size());

			renderJSON(json.toString());
		}
	}

	/**
	 * Notifies the user with the idea that another users wants to share with
	 * 
	 * @author Mohamed Sekkina
	 * @param reciverUserName
	 *            String, The username of the user the idea to be shared with
	 * @param ideaId
	 *            long, The id of the idea the user wants to share
	 */
	public static void shareIdea(String recieverUserName, long ideaId) {
		JsonObject response = new JsonObject();
		IdeaDeveloper reciever = new IdeaDeveloper();
		Idea ideaToShare = new Idea();
		IdeaDeveloper sender = new IdeaDeveloper();
		try {
			reciever = IdeaDeveloper.find("username=?", recieverUserName)
					.first();
			ideaToShare = Idea.findById(ideaId);
			sender = IdeaDeveloper.find("username=?", Security.connected())
					.first();
		} catch (Exception e) {
			response.addProperty("response",
					"Sorry, you can't share the idea with that user!");
			renderJSON(response.toString());
			return;
		}

		if (!IdeaDeveloper.canViewIdea(reciever, ideaToShare)) {
			response.addProperty("response",
					"Sorry, this user is not authorized to view this idea!");
		} else {
			String body = " has shared this idea : <p><a href=\"http://localhost:9000/topicideacontroller/checkauthorizationtoviewidea?ideaId="
					+ ideaId + "\">" + ideaToShare.title + "</a></p>";
			Notification.notify(body, reciever, sender, new Date());
			response.addProperty("response", "Shared successfully!");
		}
		renderJSON(response.toString());
	}

	/**
	 * @author AbedelRahman Badawy this method removes the relation between two
	 *         topics
	 * @param topicIdOne
	 *            long Id of the first topic
	 * @param relationName
	 *            String the name of the relation
	 */
	public static void removeTopicRelation(long topicIdOne, String relationName) {

		JsonObject json = new JsonObject();
		IdeaDeveloper idev = IdeaDeveloper.findById(Security.userid());
		TopicRelation c = (TopicRelation) TopicRelation
				.find("select tr from TopicRelation tr where tr.firstTopic=? or tr.secondTopic =? and tr.relationName=?",
						topicIdOne, topicIdOne, relationName).fetch().get(0);

		Topic one = Topic.findById(topicIdOne);

		Organization org = one.orgWhereTopicExist();
		boolean flag = false;
		for (int i = 0; i < org.managers.size(); i++) {
			if (org.managers.get(i).ideaDeveloper.equals(idev)) {
				flag = true;
				break;
			}

		}
		if (flag) {

			String x = TopicRelation.DelteRelationsTopics(c.id);
			json.addProperty("box", x);
		} else {
			// json.addProperty("box",
			// "Operation not allowed!! You are not the lead of the organization");
			Topic two = Topic.findById(c.secondTopic);
			if (one.topicEnt != null && two.topicEnt != null
					&& one.topicEnt.equals(two.topicEnt)) {
				Entities ent = one.topicEnt;
				boolean bool = false;
				for (int i = 0; i < ent.managers.size(); i++) {
					if (ent.managers.get(i).ideaDeveloper.equals(idev)) {
						bool = true;
						break;
					}

				}
				if (bool) {
					String x = TopicRelation.DelteRelationsTopics(c.id);
					json.addProperty("box", x);
				} else {
					json.addProperty(
							"box",
							"Operation not allowed!! You are not the lead of the organization neither organizer of the entity where the topic lies ");
				}

			} else {
				json.addProperty(
						"box",
						"Operation not allowed!! You are not the lead of the organization neither organizer of the entity where the topic lies ");
			}
		}

		renderJSON(json.toString());

	}

	/**
	 * Notifies the user with the topic that another users wants to share with
	 * 
	 * @author Mohamed Sekkina
	 * @param reciverUserName
	 *            String, The username of the user the topic to be shared with
	 * @param topicId
	 *            long, The id of the topic the user wants to share
	 */
	public static void shareTopic(String recieverUserName, long topicId) {
		JsonObject response = new JsonObject();
		IdeaDeveloper reciever = new IdeaDeveloper();
		Topic topicToShare = new Topic();
		IdeaDeveloper sender = new IdeaDeveloper();
		try {
			reciever = IdeaDeveloper.find("username=?", recieverUserName)
					.first();
			topicToShare = Topic.findById(topicId);
			sender = IdeaDeveloper.find("username=?", Security.connected())
					.first();
		} catch (Exception e) {
			response.addProperty("response",
					"Sorry, you can't share the topic with that user!");
			renderJSON(response.toString());
			return;
		}
		if (!IdeaDeveloper.canViewTopic(reciever, topicToShare)) {
			response.addProperty("response",
					"Sorry, this user is not authorized to view this topic!");
		} else {
			String body = " has shared this topic : <a href=\"http://localhost:9000/topicideacontroller/checkauthorizationtoviewtopic?topicId="
					+ topicId + "\">" + topicToShare.title + "</a>";
			Notification.notify(body, reciever, sender, new Date());
			response.addProperty("response", "Shared successfully!");
		}
		renderJSON(response.toString());
	}
        
        /**
	 * @author AbedelRahman Badawy
	 * this method renames a relation
	 * @param topicIdOne long id of the first topic
	 * @param relationName   String old name of the relation
	 * @param newname String new name of the relation
	 */
	public static void renameTopicRelation(long topicIdOne, String relationName,String newname) {

		JsonObject json = new JsonObject();
		IdeaDeveloper idev = IdeaDeveloper.findById(Security.userid());
		TopicRelation c = (TopicRelation) TopicRelation
				.find("select tr from TopicRelation tr where tr.firstTopic=? or tr.secondTopic =? and tr.relationName=?",
						topicIdOne, topicIdOne, relationName).fetch().get(0);

		Topic one = Topic.findById(topicIdOne);

		Organization org = one.orgWhereTopicExist();
		boolean flag = false;
		for (int i = 0; i < org.managers.size(); i++) {
			if (org.managers.get(i).ideaDeveloper.equals(idev)) {
				flag = true;
				break;
			}

		}
		if (flag) {
			c.relationName=newname;
			c.save();
			
			json.addProperty("box", "Name of the relation changed successfully");
		} else {
			// json.addProperty("box",
			// "Operation not allowed!! You are not the lead of the organization");
			Topic two = Topic.findById(c.secondTopic);
			if (one.topicEnt != null && two.topicEnt != null
					&& one.topicEnt.equals(two.topicEnt)) {
				Entities ent = one.topicEnt;
				boolean bool = false;
				for (int i = 0; i < ent.managers.size(); i++) {
					if (ent.managers.get(i).ideaDeveloper.equals(idev)) {
						bool = true;
						break;
					}

				}
				if (bool) {
					c.relationName=newname;
					c.save();
					
					json.addProperty("box", "Name of the relation changed successfully");
				} else {
					json.addProperty(
							"box",
							"Operation not allowed!! You are not the lead of the organization neither organizer of the entity where the topic lies ");
				}

			} else {
				json.addProperty(
						"box",
						"Operation not allowed!! You are not the lead of the organization neither organizer of the entity where the topic lies ");
			}
		}

		renderJSON(json.toString());

	}
	
	/**
	 * @author AbedelRahman Badawy
	 * this method renames a relation
	 * @param entityIdOne long id of the first entity
	 * @param relationName   String old name of the relation
	 * @param newname String new name of the relation
	 */
	public static void renameEntityRelation(long entityIdOne,
			String relationName,String newname) {
		JsonObject json = new JsonObject();
		IdeaDeveloper idev = IdeaDeveloper.findById(Security.userid());
		Entities one = Entities.findById(entityIdOne);
		EntityRelation c = (EntityRelation) EntityRelation
				.find("select tr from EntityRelation tr where tr.firstEntity=? or tr.secondEntity =? and tr.relationName=?",
						entityIdOne, entityIdOne, relationName).fetch().get(0);

		Organization org = one.liesIn;
		boolean flag = false;
		for (int i = 0; i < org.managers.size(); i++) {
			if (org.managers.get(i).ideaDeveloper.equals(idev)) {
				flag = true;
				break;
			}

		}
		if (flag) {

			c.relationName=newname;
			c.save();
			json.addProperty("box", "The relation is renamed successfully");
		} else {
			json.addProperty("box",
					"Operation not allowed!! You are not the lead of the organization");
		}
		renderJSON(json.toString());
	}
}
